static void alloc_monitor_pagetable(struct exec_domain *ed)
{
unsigned long mmfn;
- l2_pgentry_t *mpl2e, *phys_table;
+ l2_pgentry_t *mpl2e;
struct pfn_info *mmfn_info;
struct domain *d = ed->domain;
ed->arch.monitor_table = mk_pagetable(mmfn << PAGE_SHIFT);
ed->arch.monitor_vtable = mpl2e;
- phys_table = (l2_pgentry_t *)
- map_domain_mem(pagetable_val(ed->arch.phys_table));
- memcpy(d->arch.mm_perdomain_pt, phys_table,
- L1_PAGETABLE_ENTRIES * sizeof(l1_pgentry_t));
-
- unmap_domain_mem(phys_table);
+ // map the phys_to_machine map into the Read-Only MPT space for this domain
+ mpl2e[l2_table_offset(RO_MPT_VIRT_START)] =
+ mk_l2_pgentry(pagetable_val(ed->arch.phys_table) | __PAGE_HYPERVISOR);
}
/*
idle_pg_table[l2_table_offset(IOREMAP_VIRT_START)] =
mk_l2_pgentry(__pa(ioremap_pt) | __PAGE_HYPERVISOR);
- /* Create read-only mapping of MPT for guest-OS use. */
+ /* Create read-only mapping of MPT for guest-OS use.
+ * NB. Remove the global bit so that shadow_mode_translate()==true domains
+ * can reused this address space for their phys-to-machine mapping.
+ */
idle_pg_table[l2_table_offset(RO_MPT_VIRT_START)] =
mk_l2_pgentry(l2_pgentry_val(
- idle_pg_table[l2_table_offset(RDWR_MPT_VIRT_START)]) & ~_PAGE_RW);
+ idle_pg_table[l2_table_offset(RDWR_MPT_VIRT_START)]) &
+ ~(_PAGE_RW | _PAGE_GLOBAL));
/* Set up mapping cache for domain pages. */
mapcache = (unsigned long *)alloc_xenheap_page();
/*
* The phys_to_machine_mapping is the reversed mapping of MPT for full
- * virtualization.
+ * virtualization. It is only used by shadow_mode_translate()==true
+ * guests, so we steal the address space that would have normally
+ * been used by the read-only MPT map.
*/
-#define __phys_to_machine_mapping ((unsigned long *)PERDOMAIN_VIRT_START)
+#define __phys_to_machine_mapping ((unsigned long *)RO_MPT_VIRT_START)
/* Returns the machine physical */
static inline unsigned long phys_to_machine_mapping(unsigned long pfn)
unsigned long mfn;
l1_pgentry_t pte;
- if (__get_user(l1_pgentry_val(pte), (__phys_to_machine_mapping + pfn))) {
- return 0;
- }
-
- mfn = l1_pgentry_to_phys(pte) >> PAGE_SHIFT;
+ if (__get_user(l1_pgentry_val(pte), (__phys_to_machine_mapping + pfn)))
+ mfn = 0;
+ else
+ mfn = l1_pgentry_to_phys(pte) >> PAGE_SHIFT;
+
return mfn;
}
#define set_machinetophys(_mfn, _pfn) machine_to_phys_mapping[(_mfn)] = (_pfn)